# Create your views here.
# python manage.py runserver
from rest_framework.views import APIView
from rest_framework.response import Response
from users.models import UserModel,SfLogin,UserAmount_record,RechargeModel,VipModel,VipRecordModel
from users.models import ContractModel,ContractUserModel,Classify,Trade_TypeModel,ProfessionType
# from users.models import ProjectDemandModel,ProjectDemand1Model,ProjectDemand2Model
from django.http import HttpResponse
import re,string,requests
import random,time,json
from random import randint

from celery_tasks.sms_code.tasks import send_message
from datetime import datetime
from utils.my_redis import r
from django.contrib.auth.hashers import check_password,make_password

# 注册
# from django.conf import settings
# settings.configure(DEBUG=True) # 声明


from captcha.image import ImageCaptcha
class Imgcode(APIView):
    def get(self,request,uuid):
        code= ''.join(random.sample(string.ascii_letters + string.digits, 4))
        cap = ImageCaptcha()
        img_code = cap.generate(code)
        r.set_str(uuid,code,120)
        return HttpResponse(img_code,content_type='image/png')




class SendSmsCode(APIView):
    def get(self,request):
        mobile = request.GET.get('mobile')
        img_code = request.GET.get('img_code')
        uuid = request.GET.get('uuid')
        if not all([mobile,img_code,uuid]):
            return Response({'code': 401, 'msg': '信息不完整'})
        r_code = r.get_str(uuid)
        if not r_code:
            return Response({'code': 401, 'msg': '图片验证码过期'})

        print(r_code)
        if img_code.lower() != r_code.decode().lower():
            return Response({'code': 401, 'msg': '图片验证码错误'})
        data = randint(100000, 999999)
        resp = send_message(mobile,data)
        print('resp>>>',resp,type(resp)) # resp:json字典
        if resp:
            # 短信发送成功后，写入redis便于后边校验
            r.set_str('sms_%s'%mobile,data,600)
            return Response({'msg':'发送成功','code':200,'data':data})
        else:
            return Response({'msg':'发送失败','code':500})


class Register(APIView):
    def post(self,request):
        password = request.data.get('password')
        mobile = request.data.get('mobile')
        user_type = int(request.data.get('user_type'))
        code = request.data.get('code')
        new_code = r.get_str('sms_%s' % mobile)
        if not all([password,mobile,code]):
            return Response({'code': 204, 'msg': '信息不完整'})
        if not re.findall(r'^1[3-9]\d{9}$', mobile):
            return Response({'code': 204, 'msg': '手机号格式错误'})
        if UserModel.objects.filter(mobile=mobile):
            return Response({'code': 400, 'msg': '手机号重复'})
        if new_code.decode()!=code:
            return Response({"code": 400, "msg": "验证码错误"})
        s = datetime.strftime(datetime.now(), "%m%d")
        n = s + mobile[-4:]
        username='用户_'+n
        new_pwd = make_password(password)
        UserModel.objects.create(username=username,password=new_pwd,mobile=mobile,user_type=user_type)
        return Response({'code': 200, 'msg': '注册完成'})

# 登录



import jwt
from django.conf import settings

def login_jwt_token(user):
    payload={
        'userid': user.id,
        'username': user.username,
        'mobile': user.mobile,
        "exp_time": int(time.time())
    }

    token=jwt.encode(payload=payload,key=settings.SECRET_KEY,algorithm='HS256')
    return token




class Login(APIView):
    def post(self,request):
        mobile = request.data.get('mobile')
        pwd= request.data.get('password')

        if not mobile:
            return Response({'code': 404, 'msg': '手机号为空'})
        if not re.findall(r'^\w{6,20}$', pwd):
            return Response({'code': 204, 'msg': '密码格式错误'})
        try:
            user= UserModel.objects.get(mobile=mobile)
        except Exception as e:
            print(e)
            return Response({'code': 404, 'msg': '用户不存在'})
        print(user.password)
        if not check_password(pwd, user.password):
            return Response({'code': 204, 'msg': '账号或密码错误'})
        token= login_jwt_token(user)
        return Response({
            'code': 200,
            'msg': '欢迎用户%s登录'% user.username,
            'token': token
        })

# 第三方登录

class Sina(APIView):
    def get(self,request):
        # App Key   应用ID
        client_id = "3674019597"
        # App Secret
        client_secret = "7ae99bc0d54ead29fc8d1b9fabd78587"
        # 微博回调网址
        redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
        # 微博跳转网址
        sina_url = "https://api.weibo.com/oauth2/authorize"

        url = "https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code" % (
            client_id, redirect_uri)
        # 返回跳转地址
        return Response({'code': 200,'url':url})

from django.shortcuts import redirect
from utils.my_jwt import myjwt
class Sf_Loginview(APIView):
    def get(self,request):
        code = request.GET.get('code')
        # print(code)
        data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
                "grant_type": "authorization_code",
                'redirect_uri': 'http://127.0.0.1:8000/user/weiboCallback/', 'code': code}
        res1 = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
        mes = json.loads(res1.text)
        # print('___',mes)
        uid = mes['uid']
        token = mes['access_token']
        res=SfLogin.objects.filter(uid=uid).first()
        if res:
            user = UserModel.objects.get(id=res["userid_id"])
            jwt = {"data": {"userid": user['id'], "mobile": user["mobile"], "exptime": int(time.time())}}
            token = myjwt.jwt_encode(jwt)

            return redirect("http://127.0.0.1:8080/updatoken?token=" + token + "&userid=" + str(res['id']))
        else:
            return redirect("http://127.0.0.1:8080/weibo?token="+str(token)+"&uid="+str(uid))
    def post(self,request):
        data = json.loads(self.request.body)
        uid = data['uid']
        token = data['token']
        mobile=data['mobile']
        if not all([uid,mobile,token]):
            return Response({'code': 400, 'msg': '信息不完整'})
        user = UserModel.objects.filter(mobile=mobile).first()
        if not user:
            s = datetime.strftime(datetime.now(), "%m%d")
            n = s + mobile[-4:]
            username = '用户_' + n
            UserModel.objects.create(username=username, password='123456', mobile=mobile)
        user = UserModel.objects.filter(mobile=mobile).first()
        SfLogin.objects.create(userid_id=user.id, webfrom='weibo', token=token, uid=uid,url='')
        jwt = {"data": {"userid": user.id, "mobile": mobile,"exp_time": int(time.time())}}
        token = myjwt.jwt_encode(jwt)
        return Response({'code': 200, 'msg': 'ok', 'token': token,'userid':uid})

from utils.mysql_db import dbs

# 充值/提现
from utils.pay import get_ali_object,get_alipay_vip

class RechargePayurl(APIView):
    def get(self,request):
        # 获取支付的参数
        # data = json.loads(self.request.body)
        userid = request.GET.get('userid')
        # userid = 8
        money = float(request.GET.get('money'))
        order_name = request.GET.get('order_name')
        if money<=0:
            return Response({'code': 400, 'msg': '金额为空'})
        order_id = '010' + str(int(time.time())) + str(userid) + str(random.randint(100000, 999999))

        name='用户'+str(userid) + order_name
        RechargeModel.objects.create(money=money,order_id=order_id,userid_id=userid)

        pkey = 'order_payfail_recharge'
        r.zset_add(pkey, order_id, int(time.time()))
        pay = get_ali_object()
        query_params = pay.direct_pay(
            subject=name,  # 商品简单描述
            out_trade_no=order_id,  # 用户购买的商品订单号（每次不一样） 20180301073422891
            total_amount=float(money),  # 交易金额(单位: 元 保留俩位小数)
        )
        pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
        return Response({'code': 200, 'msg': 'ok', 'url': pay_url})



class RechargeCallback(APIView):
    def get(self,request):
        data = request.GET

        # 对参数进行处理
        data = data.dict()
        print(data)
        # 从字典中将sign删除
        sign = data.pop("sign")
        # 获取支付宝对象

        alipay = get_ali_object()
        # 调用验签
        flag = alipay.verify(data, sign)

        print(flag)
        if flag == True:
            trade_no =request.GET.get('trade_no')
            print('-_|_-',trade_no)
            out_trade_no = request.GET.get('out_trade_no')  # 订单号
            res=RechargeModel.objects.filter(order_id=out_trade_no).first()
            userid = res.userid_id
            money = res.money
            try:
                RechargeModel.objects.filter(order_id=res.order_id).update(status=1)

                users = UserModel.objects.filter(id=userid).first()
                moneys = users.money
                if moneys == 0:
                    UserModel.objects.filter(id=userid).update(money=money)
                else:
                    new_money = float(moneys) + float(money)
                    UserModel.objects.filter(id=userid).update(money=new_money)

                UserAmount_record.objects.create(type=1,status=0,user_id=userid,money=money)
                r.zset_del("order_payfail_recharge", out_trade_no)
                return redirect("http://localhost:8080/user")
            except:
                return redirect("http://localhost:8080/user")

def updateorders(out_trade_no,trade_no):
    res = RechargeModel.objects.filter(order_id=out_trade_no).first()
    userid = res.userid_id
    money = float(res.money)

    try:
        sql = "update recharge_model set static=1 where order_id='%s'" % (out_trade_no)
        dbs.add(sql)
        sql3 = "select * from user where id='%d'" % (userid)
        users = dbs.findone(sql3)
        moneys = users['money']
        aa = float(moneys) + float(money)
        sql = "update user set money='%d' where id=%d" % (aa, userid)
        dbs.add(sql)
        dbs.commit()
    except:
        dbs.rollback()

def CheckRecharge():
    # "orderpayfail"
    #从队列中获取订单号
    endtime = int(time.time())-1800
    list = r.zset_byscore("order_payfail_recharge",0,endtime)
    alipay=get_ali_object()

    #根据订单号去支付宝查询支付结果
    for i in list:
        orderno = i.decode()
        # 生成支付的url
        query_params =alipay.query_pay(out_trade_no=orderno)
        pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）

        res = requests.get(pay_url)
        mes = json.loads(res.content)
        print(mes)
        if mes['alipay_trade_query_response']['code'] == "10000":
            #根据结果更新订单状态
            updateorders(orderno,mes['alipay_trade_query_response']['trade_no'])
            r.zset_del("order_payfail_recharge", orderno)
            print('成功')
        else:
            #把订单状态改为支付失败
            print('错误')
            sql= "update recharge_model set static=2 where id=%s"%(int(orderno))
            dbs.add(sql)
            dbs.commit()
            #从队列中移除
            r.zset_del("order_payfail_recharge",orderno)




#  vip


class Set_vipView(APIView):
    def get(self,request):
        userid = request.GET.get('userid')
        # userid = 8
        money = float(request.GET.get('money'))   # 前端传来的365元或者 账户上剩余的钱（账号上钱小于365）
        pay_money = float(request.GET.get('pay_money'))  # 0 或者 365 -money
        order_name = request.GET.get('order_name')
        if money<0:
            return Response({'code': 400, 'msg': '金额错误'})
        order_id = '010' + str(int(time.time())) + str(userid) + str(random.randint(100000, 999999))
        name='用户'+str(userid) + order_name
        user=UserModel.objects.filter(id=userid).first()   # 查看用户
        try:
            VipRecordModel.objects.create(money=money, order_id=order_id, userid_id=userid,
                                          active_money=pay_money)  # 会员记录表
            if user.money >= money:  # 账号金额大于365
                user_money = float(user.money)
                new_money = user_money - money  # 更改账号金额
                UserModel.objects.filter(id=userid).update(money=new_money)
                UserAmount_record.objects.create(type=2, status=3, user_id=userid, money=money)  # 账号金额变化记录

                vip = VipModel.objects.filter(userid_id=userid).first()
                import datetime
                if vip:
                    end = vip.end_time.strftime('%Y-%m-%d %H:%M:%S')
                    # print(end)
                    now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    now_time = datetime.datetime.now()
                    if end > now:
                        end_time = vip.end_time + datetime.timedelta(hours=24 * 365)
                        VipModel.objects.filter(userid_id=userid).update(end_time=end_time)
                    else:
                        VipModel.objects.filter(userid_id=userid).update(
                            end_time=now_time + datetime.timedelta(hours=24 * 365))
                else:
                    # 会员记录表
                    n = datetime.datetime.now()
                    m = datetime.timedelta(hours=24 * 365)
                    num = n + m
                    VipModel.objects.create(userid_id=userid, end_time=num)
                VipRecordModel.objects.filter(userid_id=userid).update(status=1)
                return Response({'code': 200, 'msg': '成功'})
        except Exception as e:
            print(e)

        pkey = 'order_payfail_vip'
        r.zset_add(pkey, order_id, int(time.time()))
        pay = get_alipay_vip()
        query_params = pay.direct_pay(
            subject=name,  # 商品简单描述
            out_trade_no=order_id,  # 用户购买的商品订单号（每次不一样） 20180301073422891
            total_amount=float(pay_money),  # 交易金额(单位: 元 保留俩位小数)
        )
        pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
        return Response({'code': 201, 'msg': 'ok', 'url': pay_url})

class VipCallback(APIView):
    def get(self,request):
        data = request.GET

        # 对参数进行处理
        data = data.dict()
        print(data)
        # 从字典中将sign删除
        sign = data.pop("sign")
        # 获取支付宝对象

        alipay = get_ali_object()
        # 调用验签
        flag = alipay.verify(data, sign)

        print(flag)
        if flag == True:
            trade_no =request.GET.get('trade_no')
            print('-_|_-',trade_no)
            out_trade_no = request.GET.get('out_trade_no')  # 订单号
            res=VipRecordModel.objects.filter(order_id=out_trade_no).first()
            userid = res.userid_id
            money = res.money    # 要支付的账号里的余额（小于365）
            active_money=res.active_money    #（第三方支付需要支付的钱）
            try:
                VipRecordModel.objects.filter(order_id=res.order_id).update(status=1)

                users = UserModel.objects.filter(id=userid).first()
                moneys = users.money
                new=moneys-money
                UserModel.objects.filter(id=userid).update(money=new) # 或者直接为0
                UserAmount_record.objects.create(type=2, status=3, user_id=userid, money=money)  # 账号金额变化记录
                vip = VipModel.objects.filter(userid_id=userid).first()
                import datetime
                if vip:
                    end = vip.end_time.strftime('%Y-%m-%d %H:%M:%S')
                    # print(end)
                    now_time=datetime.datetime.now()
                    now =datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    if end > now:
                        end_time = vip.end_time + datetime.timedelta(hours=24 * 365)
                        VipModel.objects.filter(userid_id=userid).update(end_time=end_time)
                    else:
                        VipModel.objects.filter(userid_id=userid).update(
                            end_time=now_time + datetime.timedelta(hours=24 * 365))
                else:
                    # 会员记录表
                    n = datetime.datetime.now()
                    m = datetime.timedelta(hours=24 * 365)
                    num = n + m
                    VipModel.objects.create(userid_id=userid, end_time=num)
                r.zset_del("order_payfail_vip", out_trade_no)
                return redirect("http://localhost:8080/user")
            except:
                return redirect("http://localhost:8080/user")

# 用户信息
class UsersView(APIView):
    def get(self,request):
        id = request.GET.get('userid')
        users = UserModel.objects.get(id=id)
        dat={
            'username':users.username,
            'mobile':users.mobile,
            'money':users.money,
            'lock_money':users.lock_money,
            'user_type':users.user_type,
            'status':users.status,
            'image_url':users.images,
        }
        return Response({
            'code':200,
            'msg': '成功',
            'data': dat
        })

class ContractView(APIView):   # 合同
    def get(self,request):
        cons =ContractModel.objects.all()
        lis=[]
        for i in cons:
            dat = {
                'name': i.name,
            }
            lis.append(dat)
        return Response({
            'code':200,
            'msg': '成功',
            'data': lis
        })


def create_ordercode(tablename,count):
    #生成唯一id
    from utils.showflake import worker

    code =worker.get_id()

    number = hash(code)%int(count)
    if number == 0:
        return tablename,code
    else:
        return tablename + str(number),code

def set_audit():
    # 查询所有审核员角色表中添加一个角色审核员    给标的分配审核员
    sqls = "select id from admin_user where role_id=2"
    res = dbs.find_all(sqls)
    print(1111)
    for i in res:
        # 获取队列的数据


        code = r.rpop('project_demand')
        # 不为空
        if code != None:
            # 哈希取模
            code=int(code.decode())
            number = hash(code) % 3
            print("number", number)
            if number == 0:
                sqls = "update project_demand set audit_userid=%d where code=%d" % (int(i["id"]), int(code))
                dbs.add(sqls)
                dbs.commit()
                print("if标的分配成功")
            else:
                landmarks = "project_demand" + str(number)
                sql1 = "update %s set audit_userid=%d where code=%d" % (landmarks,int(i["id"]),int(code))
                dbs.add(sql1)
                dbs.commit()
                print("标的分配成功")
        else:
            print("队列没有数据")

class ProjectDemandView(APIView):   # 发需求
    def post(self,request):
        title = request.data.get('title')
        describe = request.data.get('describe')
        cid = int(request.data.get('cid'))
        money = float(request.data.get('money'))
        money_max = float(request.data.get('money_max'))
        way_type = int(request.data.get('way_type'))
        uid = int(request.data.get('userid'))
        tablename, code = create_ordercode("project_demand", 3)
        print(tablename,code)
        # print(type(code),type(money),type(money_max),type(cid),type(way_type),type(title),type(describe),type(uid))
        sql = "insert into %s (code,price,max_price,need_id,way_type,title,describes,userid_id,file_url,review_status,audit_userid,create_time) values(%d,%f,%f,%d,%d,'%s','%s',%d,'%s',%d,%d,'%s')" % (tablename,code,money,money_max,cid,way_type,str(title),describe,uid,'',0,0,datetime.now())
        dbs.add(sql)
        dbs.commit()
        # # ProjectDemandModel.objects.create(code=code,money=money,money_max=money_max,need_id=cid,way_type=way_type,title=str(title),describes=describe,userid_id=uid)
        r.lpush("project_demand", code)
        return Response({
            'code':200,
            'msg': '成功',
            'data': cid
        })


# 分类
class ClassifyAllView(APIView):
    def get(self,request):
        types = int(request.GET.get('want_id'))
        cid = int(request.GET.get('classify_id'))
        cid2 = int(request.GET.get('classify_id2'))
        cid3 = int(request.GET.get('classify_id3'))

        lis = []
        if types==0:
            if cid==0:
                sql = "select * from classify where pid=0"
                res = dbs.find_all(sql)
                res.insert(0, {'id': 0, 'name': '全部'})
                return Response({'msg': 'ok', 'code': 200,'data':res})
            else:
                if cid2==0:
                    sql = "select * from classify where pid=%d"%(cid)
                    res = dbs.find_all(sql)
                    res.insert(0, {'id': 0, 'name': '全部'})
                    return Response({'msg': 'ok', 'code': 200, 'data': res})
                else:
                    sql = "select * from classify where pid=%d" % (cid2)
                    res = dbs.find_all(sql)
                    res.insert(0, {'id': 0, 'name': '全部'})
                    return Response({'msg': 'ok', 'code': 200, 'data': res})
        elif types==1 or 2 or 3:
            if cid==0:
                sql = "select * from classify where pid=0"
                res = dbs.find_all(sql)
                res.insert(0, {'id': 0, 'name': '全部'})
                return Response({'msg': 'ok', 'code': 200,'data':res})
            else:
                if cid2==0:
                    sql = "select * from classify where pid=%d"%(cid)
                    res = dbs.find_all(sql)
                    res.insert(0, {'id': 0, 'name': '全部'})
                    return Response({'msg': 'ok', 'code': 200, 'data': res})
                else:
                    sql = "select * from classify where pid=%d" % (cid2)
                    res = dbs.find_all(sql)
                    res.insert(0, {'id': 0, 'name': '全部'})
                    return Response({'msg': 'ok', 'code': 200, 'data': res})
        elif types==4:
            if cid==0:
                sql = "select * from profession_type where pid=0"
                res = dbs.find_all(sql)
                res.insert(0, {'id': 0, 'name': '全部'})
                return Response({'msg': 'ok', 'code': 200,'data':res})
            else:
                if cid2==0:
                    sql = "select * from profession_type where pid=%d"%(cid)
                    res = dbs.find_all(sql)
                    res.insert(0, {'id': 0, 'name': '全部'})
                    return Response({'msg': 'ok', 'code': 200, 'data': res})
                else:
                    sql = "select * from profession_type where pid=%d" % (cid2)
                    res = dbs.find_all(sql)
                    res.insert(0, {'id': 0, 'name': '全部'})
                    return Response({'msg': 'ok', 'code': 200, 'data': res})
        else:
            return Response({'msg':'错误','code':400})



class Trade_typeView(APIView):   # 个人行业
    def get(self,request):
        res = Trade_TypeModel.objects.all()
        list = []
        idlist = []
        for i in res:
            if i.pid == 0:
                list.append({"id": i.id, "name": i.name, "son": []})
                idlist.append(i.pid)
        # 遍历res,把出子类和父类list进行对比，如果相同放到son,son.append
        print(list)
        for j in res:
            for index, p in enumerate(list):  # enumerate是一个函数  输出数据索引和数据
                # print(index,'-',p['id'])
                if j.pid == p['id']:
                    list[index]['son'].append({"id": j.id, "name": j.name})

        return Response({
            'code':200,
            'msg': '成功',
            'data': list
        })

class ProfessionView(APIView):   # 个人服务商专业
    def get(self,request):
        res = ProfessionType.objects.all()
        list = []
        for i in res:
            dat = {
                'id': i.id,
                'name': i.name,
                'pid': i.pid
            }
            list.append(dat)
        reslist = []
        # 读取列表中的每一个放到字典中
        dict = {}
        for i in list:
            k = i['id']
            dict[k] = i
        for j in list:
            pid = j['pid']
            if pid == 0:
                reslist.append(j)
            else:
                if 'son' not in dict[pid]:
                    dict[pid]['son'] = []
                dict[pid]['son'].append(j)
        return Response({
            'msg': 'ok',
            'code':200,
            'data': reslist
        })

class ClassifyView(APIView):
    def get(self,request):
        cons =Classify.objects.all()
        lis=[]
        for i in cons:
            dat = {
                'id':i.id,
                'name': i.name,
                'pid':i.pid
            }
            lis.append(dat)
        reslist = []
        # 读取列表中的每一个放到字典中
        dict = {}
        for i in lis:
            k = i['id']
            dict[k] = i
        for j in lis:
            pid = j['pid']
            if pid == 0:
                reslist.append(j)
            else:
                if 'son' not in dict[pid]:
                    dict[pid]['son'] = []
                dict[pid]['son'].append(j)
        # print(reslist)
        # print(dict)
        return Response({
            'msg':'ok',
            'code': 200,
            'data':reslist  # 分类无限极
        })


def getcateid(ids):   # 返回一级分类下的所有商品
    sql = 'select * from classify where pid in ('+str(ids)+')'
    res=dbs.find_all(sql)
    if res:
        ids=''
        for i in res:
            ids=ids+str(i['id'])+','
        idslis=ids.split(',')
        data=idslis[0:-1]
        strlist=','
        ids=strlist.join(data)
        print(ids)
        return getcateid(ids)
    else:
        return ids

class Anlis(APIView):
    def get(self,request):
        # s=getcateid(1)
        set_audit()
        a=settings.SECRET_KEY
        return Response({
            'msg':a,
            'data':12  # 分类无限极
        })








